﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Kugar.Core.BaseStruct;
using Kugar.Core.Data.MSSQLHelper;
using Kugar.ERPFramework.BLLInterface.Session;
using Kugar.ERPFramework.Core.Entity;
using Kugar.ERPFramework.BLLInterface;
using Kugar.Core.ExtMethod;
using Kugar.ERPFramework.Core;
using Kugar.ERPFramework.Core.Interfaces;

namespace Kugar.ERPFramework.Core
{
    public class WCFWrapper
    {
        public object GetModuleByName(string moduleName)
        {
            return null;
        }

        public T GetModuleByName<T>(string moduleName) where T : ICustomBLLModule
        {
            return default(T);
        }
        
    }

    public class ProjectInstanceWraper
    {
        private IProjectPublish _instance;
        private Dictionary<string,Lazy< ICustomBLLModule>> _cacheModule = null;
        private ISystemModule _systemModule = null;

        public ProjectInstanceWraper(IProjectPublish instance)
        {
            _instance = instance;

            var moduleInfos = _instance.GetModulePublishInfo();

            if (moduleInfos!=null && moduleInfos.Length>0)
            {
                foreach (var moduleInfo in moduleInfos)
                {
                    var module = new Lazy<ICustomBLLModule>(() => buildModule(moduleInfo));
                    _cacheModule.Add(moduleInfo.ModuleID,module);

                    if (moduleInfo.ModuleID=="SystemModule")
                    {
                        _systemModule = (ISystemModule) module.Value;
                    }
                }
            }
        }

        public ICustomBLLModule GetModuleByName(string moduleName)
        {
            var item= _cacheModule.TryGetValue(moduleName);

            if (item!=null)
            {
                return item.Value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("moduleName");
            }
        }

        private ICustomBLLModule buildModule(ModulePublishInfo info)
        {
            var binding = new NetTcpBinding(SecurityMode.None);
            var endpoint = new EndpointAddress(info.PublishUri);

            var channelFactory = new ChannelFactory<ICustomBLLModule>(binding, endpoint);

            var module = channelFactory.CreateChannel();

            return module;
        }

        public ISystemModule SystemModule { get { return _systemModule; } }

        
    }

    public interface IProjectPublish
    {
        ModulePublishInfo[] GetModulePublishInfo();
    }

    public class ModulePublishInfo
    {
        public string ModuleID { set; get; }
        public string PublishUri { set; get; }
    }

    public class SoluntionWrapper
    {
        private ISolution _solution = null;
        private ProjectInfo[] _projectList = null;
        private Dictionary<string, Lazy<IProjectPublish>> _cacheProjectInstance = new Dictionary<string, Lazy<IProjectPublish>>();

        public SoluntionWrapper(string endpointUrl)
        {
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            var endpoint = new EndpointAddress(endpointUrl);

            var channelFactory = new ChannelFactory<ISolution>(binding, endpoint);

            _solution = channelFactory.CreateChannel();

            if (_solution==null)
            {
                throw new ArgumentException("指定终结点未能正确创建服务器端对象","endpointUrl");
            }

            _projectList = _solution.GetProjectList();

            foreach (var projectInfo in _projectList)
            {
                foreach (var instance in projectInfo.InstanceList)
                {
                    instance.ProjectID = projectInfo.ProjectID;
                    _cacheProjectInstance.Add(instance.InstanceID, new Lazy<IProjectPublish>(() => buildInstance(instance), true));
                }           
            }
        }

        public IProjectPublish GetProjectInstanceByName(string instanceID)
        {
            var project = _cacheProjectInstance.TryGetValue(instanceID);

            if (project==null)
            {
                return null;
            }
            else
            {
                return project.Value;
            }
        }

        private IProjectPublish buildInstance(ProjectInstanceInfo info)
        {
            var binding = new NetTcpBinding(SecurityMode.None);
            var endpoint = new EndpointAddress(info.EndPointUrl);

            var channelFactory = new ChannelFactory<IProjectInstance>(binding, endpoint);

            var instance = channelFactory.CreateChannel();


            return null;
        }
    }
}
